// 新版redux的写法
// 引入创建store和创建slice的方法
// createSlice 返回一个slice对象(包含了reducer函数和actionCreator)
// configureStore 返回一个store对象
// createAsyncThunk 返回一个函数,这个函数有两个作用: 1. 监听异步是否完成 2. 可以作为异步的action
import { configureStore, createSlice, createAsyncThunk } from '@reduxjs/toolkit'

// 定义异步代码
// yyy类似于slice中的name
const asyncMsg = createAsyncThunk('zzz', () => {
  // 这个函数中用来写异步代码.但是必须返回一个promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 一般要执行异步操作,异步成功后拿到的数据,才是最终要使用的数据
      resolve('成功后的数据')

      // reject('失败了')
    }, 2000)
  })
})

// 创建slice
// 创建一个zs对应的slice
const zsSlice = createSlice({
  name: 'zs', //slice的名称
  initialState: { count: 1 }, //初始值
  reducers: {
    // 这个add既是reducer中的一个case.也是一个actionCreator
    add(state, action) {
      // state 可以简单理解为当前slice的数据.不是redux所有的数据.
      // 注意: 这个state不是真正的redux中当前slice所对应的数据,而是这份数据的代理.所以可以直接修改这个代理,代理内部会帮我们在reducer中返回修改后的数据
      // action就是一个需求对象{type:'xxx'}
      console.log(state, action)
      state.count = state.count + action.payload // 新版语法中action对象如果要传参数,属性名固定叫payload
    },
  },
})

// 创建一个ls对应的slice
const lsSlice = createSlice({
  name: 'ls', //slice的名称
  initialState: { msg: 'hello @reduxjs/toolkit' }, //初始值
  reducers: {
    // 这个add既是reducer中的一个case.也是一个actionCreator
    setM(state, action) {
      // state 可以简单理解为当前slice的数据.不是redux所有的数据.
      // 注意: 这个state不是真正的redux中当前slice所对应的数据,而是这份数据的代理.所以可以直接修改这个代理,代理内部会帮我们在reducer中返回修改后的数据
      // action就是一个需求对象{type:'xxx'}
      console.log(state, action)
      state.msg = action.payload // 新版语法中action对象如果要传参数,属性名固定叫payload
    },
  },
  // 由于asyncMsg要修改的是ls中的msg数据,所以在ls对应的slice中继续配置异步相关的代码
  extraReducers(builder) {
    // builder.addCase最多可以写三个,最少可以写一个
    // 三个分别代表异步正在运行(pedding),异步成功(fullfilled),异步失败(rejected)
    // 如果写一个,依旧就是成功的情况
    // builder.addCase(asyncMsg.pending, (state, action) => {
    //   // 当异步正在执行的时候,触发这个回调
    //   // state还是代理,代表当前slice中的state数据
    //   // action还是一个需求对象
    //   console.log('异步正在执行', state, action)
    // })
    builder.addCase(asyncMsg.fulfilled, (state, action) => {
      // 当异步成功的时候,触发这个函数
      console.log('异步成功了', state, action)

      state.msg = action.payload
    })
    // builder.addCase(asyncMsg.rejected, (state, action) => {
    //   // 当异步失败的的时候,触发这个函数
    //   console.log('异步失败了', state, action)
    // })
  },
})

// 创建store对象
const store = configureStore({
  reducer: {
    // zsSlice.reducer返回新版redux内部我们创建好的reducer函数
    zs: zsSlice.reducer,
    ls: lsSlice.reducer,
  },
})

store.subscribe(() => {
  console.log(store.getState())
})

// 获取张三的actionCreator
// add就是一个actionCreator
const { add } = zsSlice.actions
//  type: 'zs/add'中的zs是slice的name
// console.log(add(9)) //{type: 'zs/add', payload: 9}

const { setM } = lsSlice.actions

// store.dispatch(add(9))
// store.dispatch(setM('哈哈哈'))

// 让异步执行
store.dispatch(asyncMsg(999))
